package com.rayo.accesscontrollercopy.model.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rayo.accesscontrollercopy.model.biz.NetworkBiz;
import com.rayo.accesscontrollercopy.model.callback.ApiCallback;
import com.rayo.accesscontrollercopy.model.callback.OnGetDbListener;
import com.rayo.accesscontrollercopy.model.callback.OnNetworkListener;
import com.rayo.accesscontrollercopy.model.callback.OnUpdateDbListener;
import com.rayo.accesscontrollercopy.model.network.ApiCmd;
import com.rayo.accesscontrollercopy.model.network.bean.BaseApi;
import com.rayo.accesscontrollercopy.module.main.OpenFragment;
import com.rayo.wallreader.serialport.PortClass;
import com.rayo.wallreader.serialport.ReaderPort;
import com.rayo.wallreader.serialport.ReaderPortThread;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by yanghaojie on 2017/3/15.
 */

public class NetWorkService extends Service {
    private NetworkBiz mNetworkBiz = new NetworkBiz(this);
    private Intent intent = new Intent();
    private NetWorkHeartThread mNetWorkHeartThread;
    private ExecutorService mExecutorService = null;

    ReaderPortThread thread;
    private final IBinder mBinder = new LocalBinder();

    public final static String EXTRA_DATA = "com.rayo.network.EXTRA_DATA";
    public static boolean STATES =true ;

    public static final String ACTION_NETWORK_CONNECT = "com.rayo.network.connect";
    public static final String ACTION_NETWORK_DISCONNECT = "com.rayo.network.disconnect";
    public static final String ACTION_NETWORK_FAILED = "com.rayo.network.FAILED";
    public static final String ACTION_NETWORK_UPDATE_DB = "com.rayo.network.update.db";
    public static final String ACTION_NETWORK_UPDATE_APP = "com.rayo.network.update.app";
    public static final String ACTION_NETWORK_SEND = "com.rayo.network.send";
    public static final String ACTION_NETWORK_API_SUCCESS = "com.rayo.network.api.success";
    public static final String ACTION_NETWORK_API_ERROR = "com.rayo.network.api.error";
    public static final String ACTION_NETWORK_API_FAILED = "com.rayo.network.api.failed";
    public static final String ACTION_NETWORK_OPEN = "com.rayo.network.api.open";
    public static final String ACTION_NETWORK_CONNECTING = "com.rayo.network.connecting";

    private final OnNetworkListener mOnNetworkListener = new OnNetworkListener() {

        @Override
        public <T> void onSuccess(String action, T data) {
            switch (action) {
                case ACTION_NETWORK_CONNECTING:
                    mNetWorkHeartThread.setSend_time();
                    mNetWorkHeartThread.onPause();
                    break;
                case ACTION_NETWORK_SEND:
                    BaseApi baseApi= JSON.parseObject((String) data,BaseApi.class);
                    if(baseApi.getCmd()== ApiCmd.OPEN||baseApi.getCmd()==ApiCmd.UPDATE_LOCK||baseApi.getCmd()==ApiCmd.ERROR){

                    }
                    else {
                        mNetWorkHeartThread.setSend_time();
                        mNetWorkHeartThread.onPause();
                    }
                    break;
                case ACTION_NETWORK_CONNECT:
                    broadcastUpdate(ACTION_NETWORK_CONNECT, new NetworkData(data));
                    break;
                case ACTION_NETWORK_DISCONNECT:
                    setThreadStart();
                    broadcastUpdate(ACTION_NETWORK_DISCONNECT, new NetworkData(data));
                    break;
                case ACTION_NETWORK_FAILED:
                    setThreadStart();
                    broadcastUpdate(ACTION_NETWORK_FAILED, new NetworkData(data));
                    break;
                case ACTION_NETWORK_UPDATE_DB:
                    broadcastUpdate(ACTION_NETWORK_UPDATE_DB, new NetworkData(data));
                    break;
                case ACTION_NETWORK_UPDATE_APP:
                    broadcastUpdate(ACTION_NETWORK_UPDATE_APP, new NetworkData(ApiCmd.UPDATE_APP, data));
                    break;

                default:
                    break;
            }
        }

        @Override
        public void onFailed(String action, String error) {

        }

        @Override
        public void onTimeOut() {
            setThreadStart();
        }
    };

    private final OnGetDbListener mOnGetDbListener = new OnGetDbListener() {
        @Override
        public <T> void onSuccess(T t) {
            broadcastUpdate(ACTION_NETWORK_UPDATE_DB, new NetworkData(t));
        }

        @Override
        public void onFailed(int error) {
            broadcastUpdate(ACTION_NETWORK_UPDATE_DB, new NetworkData(error));
        }
    };

    private final OnUpdateDbListener mOnUpdateDbListener = new OnUpdateDbListener() {

        @Override
        public <T> void onSuccess(String action, T t) {

        }

        @Override
        public void onFailed(String action, String error) {
            broadcastUpdate(ACTION_NETWORK_UPDATE_DB, new NetworkData(error));
        }
    };

    private void setThreadStart(){
        mNetWorkHeartThread.setSend_time();
        mNetWorkHeartThread.onResume();
    }
    private final ApiCallback mApiCallback = new ApiCallback() {
        @Override
        public void onSuccess(byte cmd, JSONObject jsonObject) {
//            mNetWorkHeartThread.setSend_time();
            setThreadStart();
            NetworkData networkData = mNetworkBiz.saveData(cmd, jsonObject);
            if (ApiCmd.OPEN == cmd) return;
            broadcastUpdate(ACTION_NETWORK_API_SUCCESS, networkData);
        }

        @Override
        public void onError(byte cmd,String err_msg) {
            setThreadStart();
            NetworkData networkData=new NetworkData();
            networkData.setCmd(cmd);
            networkData.setData(err_msg);
            broadcastUpdate(ACTION_NETWORK_API_ERROR, networkData);
        }

        @Override
        public void onFailure() {
            broadcastUpdate(ACTION_NETWORK_API_FAILED, null);
        }
    };

    private void broadcastUpdate(String action, NetworkData networkData) {
        if (null == networkData) return;
        intent.setAction(action);
        intent.putExtra(EXTRA_DATA, networkData);
        sendBroadcast(intent);
    }

    public class LocalBinder extends Binder {
        public NetWorkService getService() {
            return NetWorkService.this;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        this.mNetworkBiz = new NetworkBiz(this);
        this.mNetworkBiz.init(mOnGetDbListener, mOnNetworkListener, mOnUpdateDbListener, mApiCallback);
        this.mNetWorkHeartThread = new NetWorkHeartThread(this.mNetworkBiz);
        this.mExecutorService = Executors.newSingleThreadExecutor();
        this.mExecutorService.execute(mNetWorkHeartThread);
        this.mNetworkBiz.connect();

        timer.schedule(task,0,40000);
    }


    Timer timer = new Timer();
    TimerTask task = new TimerTask() {

        @Override
        public void run() {
            // 需要做的事:发送消息
            if (STATES==true){
                newThread();
            }
        }
    };

    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
         if (msg.what == 1) {
            thread.stop();
         }
            super.handleMessage(msg);
        };
    };
    public void newThread(){
        List<PortClass> port = new ArrayList<>();
        PortClass portClass = new PortClass(ReaderPort.DETIVER_2,true,true,false);
        port.add(portClass);
        thread = new ReaderPortThread(port) {

            @Override
            protected void onSendNfcKeyReader(String s, int i) {

            }

            @Override
            protected void onSendBleKeyReader(String s, int i) {

            }

            @Override
            protected void onSendCardReader(String s, int i, byte[] bytes) {

            }

            @Override
            protected void onNoReader(String s, int i) {

            }

            @Override
            protected void onPlugInRelay(String s, int i) {

            }

            @Override
            protected void onStopReader() {

            }


        };
        new Thread(thread).start();

        SystemClock.sleep(1000);
        Message message = new Message();
        message.what = 1;
        handler.sendMessage(message);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        mNetWorkHeartThread.onDestory();
        mExecutorService.shutdown();
    }

}
